home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / B-C / Berkeley-yacc-mpw / output.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-14  |  22.0 KB  |  1,187 lines  |  [TEXT/MPS ]

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Robert Paul Corbett.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)output.c    5.6 (Berkeley) 1/20/91";
  39. #endif /* not lint */
  40.  
  41. #include "defs.h"
  42.  
  43. static int nvectors;
  44. static int nentries;
  45. static short **froms;
  46. static short **tos;
  47. static short *tally;
  48. static short *width;
  49. static short *state_count;
  50. static short *order;
  51. static short *base;
  52. static short *pos;
  53. static int maxtable;
  54. static short *table;
  55. static short *check;
  56. static int lowzero;
  57. static int high;
  58.  
  59.  
  60. output()
  61. {
  62.     free_itemsets();
  63.     free_shifts();
  64.     free_reductions();
  65.     output_stored_text();
  66.     output_defines();
  67.     output_rule_data();
  68.     output_yydefred();
  69.     output_actions();
  70.     free_parser();
  71.     output_debug();
  72.     output_stype();
  73.     if (rflag) write_section(tables);
  74.     write_section(header);
  75.     output_trailing_text();
  76.     write_section(body);
  77.     output_semantic_actions();
  78.     write_section(trailer);
  79. }
  80.  
  81.  
  82. output_rule_data()
  83. {
  84.     register int i;
  85.     register int j;
  86.  
  87.   
  88.     fprintf(output_file, "short yylhs[] = {%42d,",
  89.         symbol_value[start_symbol]);
  90.  
  91.     j = 10;
  92.     for (i = 3; i < nrules; i++)
  93.     {
  94.     if (j >= 10)
  95.     {
  96.         if (!rflag) ++outline;
  97.         putc('\n', output_file);
  98.         j = 1;
  99.     }
  100.         else
  101.         ++j;
  102.  
  103.         fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
  104.     }
  105.     if (!rflag) outline += 2;
  106.     fprintf(output_file, "\n};\n");
  107.  
  108.     fprintf(output_file, "short yylen[] = {%42d,", 2);
  109.  
  110.     j = 10;
  111.     for (i = 3; i < nrules; i++)
  112.     {
  113.     if (j >= 10)
  114.     {
  115.         if (!rflag) ++outline;
  116.         putc('\n', output_file);
  117.         j = 1;
  118.     }
  119.     else
  120.       j++;
  121.  
  122.         fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
  123.     }
  124.     if (!rflag) outline += 2;
  125.     fprintf(output_file, "\n};\n");
  126. }
  127.  
  128.  
  129. output_yydefred()
  130. {
  131.     register int i, j;
  132.  
  133.     fprintf(output_file, "short yydefred[] = {%39d,",
  134.         (defred[0] ? defred[0] - 2 : 0));
  135.  
  136.     j = 10;
  137.     for (i = 1; i < nstates; i++)
  138.     {
  139.     if (j < 10)
  140.         ++j;
  141.     else
  142.     {
  143.         if (!rflag) ++outline;
  144.         putc('\n', output_file);
  145.         j = 1;
  146.     }
  147.  
  148.     fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
  149.     }
  150.  
  151.     if (!rflag) outline += 2;
  152.     fprintf(output_file, "\n};\n");
  153. }
  154.  
  155.  
  156. output_actions()
  157. {
  158.     nvectors = 2*nstates + nvars;
  159.  
  160.     froms = NEW2(nvectors, short *);
  161.     tos = NEW2(nvectors, short *);
  162.     tally = NEW2(nvectors, short);
  163.     width = NEW2(nvectors, short);
  164.  
  165.     token_actions();
  166.     FREE(lookaheads);
  167.     FREE(LA);
  168.     FREE(LAruleno);
  169.     FREE(accessing_symbol);
  170.  
  171.     goto_actions();
  172.     FREE(goto_map + ntokens);
  173.     FREE(from_state);
  174.     FREE(to_state);
  175.  
  176.     sort_actions();
  177.     pack_table();
  178.     output_base();
  179.     output_table();
  180.     output_check();
  181. }
  182.  
  183.  
  184. token_actions()
  185. {
  186.     register int i, j;
  187.     register int shiftcount, reducecount;
  188.     register int max, min;
  189.     register short *actionrow, *r, *s;
  190.     register action *p;
  191.  
  192.     actionrow = NEW2(2*ntokens, short);
  193.     for (i = 0; i < nstates; ++i)
  194.     {
  195.     if (parser[i])
  196.     {
  197.         for (j = 0; j < 2*ntokens; ++j)
  198.         actionrow[j] = 0;
  199.  
  200.         shiftcount = 0;
  201.         reducecount = 0;
  202.         for (p = parser[i]; p; p = p->next)
  203.         {
  204.         if (p->suppressed == 0)
  205.         {
  206.             if (p->action_code == SHIFT)
  207.             {
  208.             ++shiftcount;
  209.             actionrow[p->symbol] = p->number;
  210.             }
  211.             else if (p->action_code == REDUCE && p->number != defred[i])
  212.             {
  213.             ++reducecount;
  214.             actionrow[p->symbol + ntokens] = p->number;
  215.             }
  216.         }
  217.         }
  218.  
  219.         tally[i] = shiftcount;
  220.         tally[nstates+i] = reducecount;
  221.         width[i] = 0;
  222.         width[nstates+i] = 0;
  223.         if (shiftcount > 0)
  224.         {
  225.         froms[i] = r = NEW2(shiftcount, short);
  226.         tos[i] = s = NEW2(shiftcount, short);
  227.         min = MAXSHORT;
  228.         max = 0;
  229.         for (j = 0; j < ntokens; ++j)
  230.         {
  231.             if (actionrow[j])
  232.             {
  233.             if (min > symbol_value[j])
  234.                 min = symbol_value[j];
  235.             if (max < symbol_value[j])
  236.                 max = symbol_value[j];
  237.             *r++ = symbol_value[j];
  238.             *s++ = actionrow[j];
  239.             }
  240.         }
  241.         width[i] = max - min + 1;
  242.         }
  243.         if (reducecount > 0)
  244.         {
  245.         froms[nstates+i] = r = NEW2(reducecount, short);
  246.         tos[nstates+i] = s = NEW2(reducecount, short);
  247.         min = MAXSHORT;
  248.         max = 0;
  249.         for (j = 0; j < ntokens; ++j)
  250.         {
  251.             if (actionrow[ntokens+j])
  252.             {
  253.             if (min > symbol_value[j])
  254.                 min = symbol_value[j];
  255.             if (max < symbol_value[j])
  256.                 max = symbol_value[j];
  257.             *r++ = symbol_value[j];
  258.             *s++ = actionrow[ntokens+j] - 2;
  259.             }
  260.         }
  261.         width[nstates+i] = max - min + 1;
  262.         }
  263.     }
  264.     }
  265.     FREE(actionrow);
  266. }
  267.  
  268. goto_actions()
  269. {
  270.     register int i, j, k;
  271.  
  272.     state_count = NEW2(nstates, short);
  273.  
  274.     k = default_goto(start_symbol + 1);
  275.     fprintf(output_file, "short yydgoto[] = {%40d,", k);
  276.     save_column(start_symbol + 1, k);
  277.  
  278.     j = 10;
  279.     for (i = start_symbol + 2; i < nsyms; i++)
  280.     {
  281.     if (j >= 10)
  282.     {
  283.         if (!rflag) ++outline;
  284.         putc('\n', output_file);
  285.         j = 1;
  286.     }
  287.     else
  288.         ++j;
  289.  
  290.     k = default_goto(i);
  291.     fprintf(output_file, "%5d,", k);
  292.     save_column(i, k);
  293.     }
  294.  
  295.     if (!rflag) outline += 2;
  296.     fprintf(output_file, "\n};\n");
  297.     FREE(state_count);
  298. }
  299.  
  300. int
  301. default_goto(symbol)
  302. int symbol;
  303. {
  304.     register int i;
  305.     register int m;
  306.     register int n;
  307.     register int default_state;
  308.     register int max;
  309.  
  310.     m = goto_map[symbol];
  311.     n = goto_map[symbol + 1];
  312.  
  313.     if (m == n) return (0);
  314.  
  315.     for (i = 0; i < nstates; i++)
  316.     state_count[i] = 0;
  317.  
  318.     for (i = m; i < n; i++)
  319.     state_count[to_state[i]]++;
  320.  
  321.     max = 0;
  322.     default_state = 0;
  323.     for (i = 0; i < nstates; i++)
  324.     {
  325.     if (state_count[i] > max)
  326.     {
  327.         max = state_count[i];
  328.         default_state = i;
  329.     }
  330.     }
  331.  
  332.     return (default_state);
  333. }
  334.  
  335.  
  336.  
  337. save_column(symbol, default_state)
  338. int symbol;
  339. int default_state;
  340. {
  341.     register int i;
  342.     register int m;
  343.     register int n;
  344.     register short *sp;
  345.     register short *sp1;
  346.     register short *sp2;
  347.     register int count;
  348.     register int symno;
  349.  
  350.     m = goto_map[symbol];
  351.     n = goto_map[symbol + 1];
  352.  
  353.     count = 0;
  354.     for (i = m; i < n; i++)
  355.     {
  356.     if (to_state[i] != default_state)
  357.         ++count;
  358.     }
  359.     if (count == 0) return;
  360.  
  361.     symno = symbol_value[symbol] + 2*nstates;
  362.  
  363.     froms[symno] = sp1 = sp = NEW2(count, short);
  364.     tos[symno] = sp2 = NEW2(count, short);
  365.  
  366.     for (i = m; i < n; i++)
  367.     {
  368.     if (to_state[i] != default_state)
  369.     {
  370.         *sp1++ = from_state[i];
  371.         *sp2++ = to_state[i];
  372.     }
  373.     }
  374.  
  375.     tally[symno] = count;
  376.     width[symno] = sp1[-1] - sp[0] + 1;
  377. }
  378.  
  379. sort_actions()
  380. {
  381.   register int i;
  382.   register int j;
  383.   register int k;
  384.   register int t;
  385.   register int w;
  386.  
  387.   order = NEW2(nvectors, short);
  388.   nentries = 0;
  389.  
  390.   for (i = 0; i < nvectors; i++)
  391.     {
  392.       if (tally[i] > 0)
  393.     {
  394.       t = tally[i];
  395.       w = width[i];
  396.       j = nentries - 1;
  397.  
  398.       while (j >= 0 && (width[order[j]] < w))
  399.         j--;
  400.  
  401.       while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
  402.         j--;
  403.  
  404.       for (k = nentries - 1; k > j; k--)
  405.         order[k + 1] = order[k];
  406.  
  407.       order[j + 1] = i;
  408.       nentries++;
  409.     }
  410.     }
  411. }
  412.  
  413.  
  414. pack_table()
  415. {
  416.     register int i;
  417.     register int place;
  418.     register int state;
  419.  
  420.     base = NEW2(nvectors, short);
  421.     pos = NEW2(nentries, short);
  422.  
  423.     maxtable = 1000;
  424.     table = NEW2(maxtable, short);
  425.     check = NEW2(maxtable, short);
  426.  
  427.     lowzero = 0;
  428.     high = 0;
  429.  
  430.     for (i = 0; i < maxtable; i++)
  431.     check[i] = -1;
  432.  
  433.     for (i = 0; i < nentries; i++)
  434.     {
  435.     state = matching_vector(i);
  436.  
  437.     if (state < 0)
  438.         place = pack_vector(i);
  439.     else
  440.         place = base[state];
  441.  
  442.     pos[i] = place;
  443.     base[order[i]] = place;
  444.     }
  445.  
  446.     for (i = 0; i < nvectors; i++)
  447.     {
  448.     if (froms[i])
  449.         FREE(froms[i]);
  450.     if (tos[i])
  451.         FREE(tos[i]);
  452.     }
  453.  
  454.     FREE(froms);
  455.     FREE(tos);
  456.     FREE(pos);
  457. }
  458.  
  459.  
  460. /*  The function matching_vector determines if the vector specified by    */
  461. /*  the input parameter matches a previously considered    vector.  The    */
  462. /*  test at the start of the function checks if the vector represents    */
  463. /*  a row of shifts over terminal symbols or a row of reductions, or a    */
  464. /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not    */
  465. /*  check if a column of shifts over a nonterminal symbols matches a    */
  466. /*  previously considered vector.  Because of the nature of LR parsing    */
  467. /*  tables, no two columns can match.  Therefore, the only possible    */
  468. /*  match would be between a row and a column.  Such matches are    */
  469. /*  unlikely.  Therefore, to save time, no attempt is made to see if a    */
  470. /*  column matches a previously considered vector.            */
  471. /*                                    */
  472. /*  Matching_vector is poorly designed.  The test could easily be made    */
  473. /*  faster.  Also, it depends on the vectors being in a specific    */
  474. /*  order.                                */
  475.  
  476. int
  477. matching_vector(vector)
  478. int vector;
  479. {
  480.     register int i;
  481.     register int j;
  482.     register int k;
  483.     register int t;
  484.     register int w;
  485.     register int match;
  486.     register int prev;
  487.  
  488.     i = order[vector];
  489.     if (i >= 2*nstates)
  490.     return (-1);
  491.  
  492.     t = tally[i];
  493.     w = width[i];
  494.  
  495.     for (prev = vector - 1; prev >= 0; prev--)
  496.     {
  497.     j = order[prev];
  498.     if (width[j] != w || tally[j] != t)
  499.         return (-1);
  500.  
  501.     match = 1;
  502.     for (k = 0; match && k < t; k++)
  503.     {
  504.         if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
  505.         match = 0;
  506.     }
  507.  
  508.     if (match)
  509.         return (j);
  510.     }
  511.  
  512.     return (-1);
  513. }
  514.  
  515.  
  516.  
  517. int
  518. pack_vector(vector)
  519. int vector;
  520. {
  521.     register int i, j, k, l;
  522.     register int t;
  523.     register int loc;
  524.     register int ok;
  525.     register short *from;
  526.     register short *to;
  527.     int newmax;
  528.  
  529.     i = order[vector];
  530.     t = tally[i];
  531.     assert(t);
  532.  
  533.     from = froms[i];
  534.     to = tos[i];
  535.  
  536.     j = lowzero - from[0];
  537.     for (k = 1; k < t; ++k)
  538.     if (lowzero - from[k] > j)
  539.         j = lowzero - from[k];
  540.     for (;; ++j)
  541.     {
  542.     if (j == 0)
  543.         continue;
  544.     ok = 1;
  545.     for (k = 0; ok && k < t; k++)
  546.     {
  547.         loc = j + from[k];
  548.         if (loc >= maxtable)
  549.         {
  550.         if (loc >= MAXTABLE)
  551.             fatal("maximum table size exceeded");
  552.  
  553.         newmax = maxtable;
  554.         do { newmax += 200; } while (newmax <= loc);
  555.         table = (short *) REALLOC(table, newmax*sizeof(short));
  556.         if (table == 0) no_space();
  557.         check = (short *) REALLOC(check, newmax*sizeof(short));
  558.         if (check == 0) no_space();
  559.         for (l  = maxtable; l < newmax; ++l)
  560.         {
  561.             table[l] = 0;
  562.             check[l] = -1;
  563.         }
  564.         maxtable = newmax;
  565.         }
  566.  
  567.         if (loc < 0 || check[loc] != -1) /* bugfix --PSP */
  568.         ok = 0;
  569.     }
  570.     for (k = 0; ok && k < vector; k++)
  571.     {
  572.         if (pos[k] == j)
  573.         ok = 0;
  574.     }
  575.     if (ok)
  576.     {
  577.         for (k = 0; k < t; k++)
  578.         {
  579.         loc = j + from[k];
  580.         table[loc] = to[k];
  581.         check[loc] = from[k];
  582.         if (loc > high) high = loc;
  583.         }
  584.  
  585.         while (check[lowzero] != -1)
  586.         ++lowzero;
  587.  
  588.         return (j);
  589.     }
  590.     }
  591. }
  592.  
  593.  
  594.  
  595. output_base()
  596. {
  597.     register int i, j;
  598.  
  599.     fprintf(output_file, "short yysindex[] = {%39d,", base[0]);
  600.  
  601.     j = 10;
  602.     for (i = 1; i < nstates; i++)
  603.     {
  604.     if (j >= 10)
  605.     {
  606.         if (!rflag) ++outline;
  607.         putc('\n', output_file);
  608.         j = 1;
  609.     }
  610.     else
  611.         ++j;
  612.  
  613.     fprintf(output_file, "%5d,", base[i]);
  614.     }
  615.  
  616.     if (!rflag) outline += 2;
  617.     fprintf(output_file, "\n};\nshort yyrindex[] = {%39d,",
  618.         base[nstates]);
  619.  
  620.     j = 10;
  621.     for (i = nstates + 1; i < 2*nstates; i++)
  622.     {
  623.     if (j >= 10)
  624.     {
  625.         if (!rflag) ++outline;
  626.         putc('\n', output_file);
  627.         j = 1;
  628.     }
  629.     else
  630.         ++j;
  631.  
  632.     fprintf(output_file, "%5d,", base[i]);
  633.     }
  634.  
  635.     if (!rflag) outline += 2;
  636.     fprintf(output_file, "\n};\nshort yygindex[] = {%39d,",
  637.         base[2*nstates]);
  638.  
  639.     j = 10;
  640.     for (i = 2*nstates + 1; i < nvectors - 1; i++)
  641.     {
  642.     if (j >= 10)
  643.     {
  644.         if (!rflag) ++outline;
  645.         putc('\n', output_file);
  646.         j = 1;
  647.     }
  648.     else
  649.         ++j;
  650.  
  651.     fprintf(output_file, "%5d,", base[i]);
  652.     }
  653.  
  654.     if (!rflag) outline += 2;
  655.     fprintf(output_file, "\n};\n");
  656.     FREE(base);
  657. }
  658.  
  659.  
  660.  
  661. output_table()
  662. {
  663.     register int i;
  664.     register int j;
  665.  
  666.     ++outline;
  667.     fprintf(code_file, "#define YYTABLESIZE %d\n", high);
  668.     fprintf(output_file, "short yytable[] = {%40d,", table[0]);
  669.  
  670.     j = 10;
  671.     for (i = 1; i <= high; i++)
  672.     {
  673.     if (j >= 10)
  674.     {
  675.         if (!rflag) ++outline;
  676.         putc('\n', output_file);
  677.         j = 1;
  678.     }
  679.     else
  680.         ++j;
  681.  
  682.     fprintf(output_file, "%5d,", table[i]);
  683.     }
  684.  
  685.     if (!rflag) outline += 2;
  686.     fprintf(output_file, "\n};\n");
  687.     FREE(table);
  688. }
  689.  
  690.  
  691.  
  692. output_check()
  693. {
  694.     register int i;
  695.     register int j;
  696.  
  697.     fprintf(output_file, "short yycheck[] = {%40d,", check[0]);
  698.  
  699.     j = 10;
  700.     for (i = 1; i <= high; i++)
  701.     {
  702.     if (j >= 10)
  703.     {
  704.         if (!rflag) ++outline;
  705.         putc('\n', output_file);
  706.         j = 1;
  707.     }
  708.     else
  709.         ++j;
  710.  
  711.     fprintf(output_file, "%5d,", check[i]);
  712.     }
  713.  
  714.     if (!rflag) outline += 2;
  715.     fprintf(output_file, "\n};\n");
  716.     FREE(check);
  717. }
  718.  
  719.  
  720. int
  721. is_C_identifier(name)
  722. char *name;
  723. {
  724.     register char *s;
  725.     register int c;
  726.  
  727.     s = name;
  728.     c = *s;
  729.     if (c == '"')
  730.     {
  731.     c = *++s;
  732.     if (!isalpha(c) && c != '_' && c != '$')
  733.         return (0);
  734.     while ((c = *++s) != '"')
  735.     {
  736.         if (!isalnum(c) && c != '_' && c != '$')
  737.         return (0);
  738.     }
  739.     return (1);
  740.     }
  741.  
  742.     if (!isalpha(c) && c != '_' && c != '$')
  743.     return (0);
  744.     while (c = *++s)
  745.     {
  746.     if (!isalnum(c) && c != '_' && c != '$')
  747.         return (0);
  748.     }
  749.     return (1);
  750. }
  751.  
  752.  
  753. output_defines()
  754. {
  755.     register int c, i;
  756.     register char *s;
  757.  
  758.     for (i = 2; i < ntokens; ++i)
  759.     {
  760.     s = symbol_name[i];
  761.     if (is_C_identifier(s))
  762.     {
  763.         fprintf(code_file, "#define ");
  764.         if (dflag) fprintf(defines_file, "#define ");
  765.         c = *s;
  766.         if (c == '"')
  767.         {
  768.         while ((c = *++s) != '"')
  769.         {
  770.             putc(c, code_file);
  771.             if (dflag) putc(c, defines_file);
  772.         }
  773.         }
  774.         else
  775.         {
  776.         do
  777.         {
  778.             putc(c, code_file);
  779.             if (dflag) putc(c, defines_file);
  780.         }
  781.         while (c = *++s);
  782.         }
  783.         ++outline;
  784.         fprintf(code_file, " %d\n", symbol_value[i]);
  785.         if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
  786.     }
  787.     }
  788.  
  789.     ++outline;
  790.     fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
  791.  
  792.     if (dflag && unionized)
  793.     {
  794.     fclose(union_file);
  795.     union_file = fopen(union_file_name, "r");
  796.     if (union_file == NULL) open_error(union_file_name);
  797.     while ((c = getc(union_file)) != EOF)
  798.         putc(c, defines_file);
  799.     fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE yylval;\n");
  800.     }
  801. }
  802.  
  803.  
  804. output_stored_text()
  805. {
  806.     register int c;
  807.     register FILE *in, *out;
  808.  
  809.     fclose(text_file);
  810.     text_file = fopen(text_file_name, "r");
  811.     if (text_file == NULL)
  812.     open_error(text_file_name);
  813.     in = text_file;
  814.     if ((c = getc(in)) == EOF)
  815.     return;
  816.     out = code_file;
  817.     if (c ==  '\n')
  818.     ++outline;
  819.     putc(c, out);
  820.     while ((c = getc(in)) != EOF)
  821.     {
  822.     if (c == '\n')
  823.         ++outline;
  824.     putc(c, out);
  825.     }
  826.     if (!lflag)
  827.     fprintf(out, line_format, ++outline + 1, code_file_name);
  828. }
  829.  
  830.  
  831. output_debug()
  832. {
  833.     register int i, j, k, max;
  834.     char **symnam, *s;
  835.  
  836.     ++outline;
  837.     fprintf(code_file, "#define YYFINAL %d\n", final_state);
  838.     outline += 3;
  839.     fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  840.         tflag);
  841.     if (rflag)
  842.     fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  843.         tflag);
  844.  
  845.     max = 0;
  846.     for (i = 2; i < ntokens; ++i)
  847.     if (symbol_value[i] > max)
  848.         max = symbol_value[i];
  849.     ++outline;
  850.     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
  851.  
  852.     symnam = (char **) MALLOC((max+1)*sizeof(char *));
  853.     if (symnam == 0) no_space();
  854.  
  855.     /* Note that it is  not necessary to initialize the element        */
  856.     /* symnam[max].                            */
  857.     for (i = 0; i < max; ++i)
  858.     symnam[i] = 0;
  859.     for (i = ntokens - 1; i >= 2; --i)
  860.     symnam[symbol_value[i]] = symbol_name[i];
  861.     symnam[0] = "end-of-file";
  862.  
  863.     if (!rflag) ++outline;
  864.     fprintf(output_file, "#if YYDEBUG\nchar *yyname[] = {");
  865.     j = 80;
  866.     for (i = 0; i <= max; ++i)
  867.     {
  868.     if (s = symnam[i])
  869.     {
  870.         if (s[0] == '"')
  871.         {
  872.         k = 7;
  873.         while (*++s != '"')
  874.         {
  875.             ++k;
  876.             if (*s == '\\')
  877.             {
  878.             k += 2;
  879.             if (*++s == '\\')
  880.                 ++k;
  881.             }
  882.         }
  883.         j += k;
  884.         if (j > 80)
  885.         {
  886.             if (!rflag) ++outline;
  887.             putc('\n', output_file);
  888.             j = k;
  889.         }
  890.         fprintf(output_file, "\"\\\"");
  891.         s = symnam[i];
  892.         while (*++s != '"')
  893.         {
  894.             if (*s == '\\')
  895.             {
  896.             fprintf(output_file, "\\\\");
  897.             if (*++s == '\\')
  898.                 fprintf(output_file, "\\\\");
  899.             else
  900.                 putc(*s, output_file);
  901.             }
  902.             else
  903.             putc(*s, output_file);
  904.         }
  905.         fprintf(output_file, "\\\"\",");
  906.         }
  907.         else if (s[0] == '\'')
  908.         {
  909.         if (s[1] == '"')
  910.         {
  911.             j += 7;
  912.             if (j > 80)
  913.             {
  914.             if (!rflag) ++outline;
  915.             putc('\n', output_file);
  916.             j = 7;
  917.             }
  918.             fprintf(output_file, "\"'\\\"'\",");
  919.         }
  920.         else
  921.         {
  922.             k = 5;
  923.             while (*++s != '\'')
  924.             {
  925.             ++k;
  926.             if (*s == '\\')
  927.             {
  928.                 k += 2;
  929.                 if (*++s == '\\')
  930.                 ++k;
  931.             }
  932.             }
  933.             j += k;
  934.             if (j > 80)
  935.             {
  936.             if (!rflag) ++outline;
  937.             putc('\n', output_file);
  938.             j = k;
  939.             }
  940.             fprintf(output_file, "\"'");
  941.             s = symnam[i];
  942.             while (*++s != '\'')
  943.             {
  944.             if (*s == '\\')
  945.             {
  946.                 fprintf(output_file, "\\\\");
  947.                 if (*++s == '\\')
  948.                 fprintf(output_file, "\\\\");
  949.                 else
  950.                 putc(*s, output_file);
  951.             }
  952.             else
  953.                 putc(*s, output_file);
  954.             }
  955.             fprintf(output_file, "'\",");
  956.         }
  957.         }
  958.         else
  959.         {
  960.         k = strlen(s) + 3;
  961.         j += k;
  962.         if (j > 80)
  963.         {
  964.             if (!rflag) ++outline;
  965.             putc('\n', output_file);
  966.             j = k;
  967.         }
  968.         putc('"', output_file);
  969.         do { putc(*s, output_file); } while (*++s);
  970.         fprintf(output_file, "\",");
  971.         }
  972.     }
  973.     else
  974.     {
  975.         j += 2;
  976.         if (j > 80)
  977.         {
  978.         if (!rflag) ++outline;
  979.         putc('\n', output_file);
  980.         j = 2;
  981.         }
  982.         fprintf(output_file, "0,");
  983.     }
  984.     }
  985.     if (!rflag) outline += 2;
  986.     fprintf(output_file, "\n};\n");
  987.     FREE(symnam);
  988.  
  989.     if (!rflag) ++outline;
  990.     fprintf(output_file, "char *yyrule[] = {\n");
  991.     for (i = 2; i < nrules; ++i)
  992.     {
  993.     fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
  994.     for (j = rrhs[i]; ritem[j] > 0; ++j)
  995.     {
  996.         s = symbol_name[ritem[j]];
  997.         if (s[0] == '"')
  998.         {
  999.         fprintf(output_file, " \\\"");
  1000.         while (*++s != '"')
  1001.         {
  1002.             if (*s == '\\')
  1003.             {
  1004.             if (s[1] == '\\')
  1005.                 fprintf(output_file, "\\\\\\\\");
  1006.             else
  1007.                 fprintf(output_file, "\\\\%c", s[1]);
  1008.             ++s;
  1009.             }
  1010.             else
  1011.             putc(*s, output_file);
  1012.         }
  1013.         fprintf(output_file, "\\\"");
  1014.         }
  1015.         else if (s[0] == '\'')
  1016.         {
  1017.         if (s[1] == '"')
  1018.             fprintf(output_file, " '\\\"'");
  1019.         else if (s[1] == '\\')
  1020.         {
  1021.             if (s[2] == '\\')
  1022.             fprintf(output_file, " '\\\\\\\\");
  1023.             else
  1024.             fprintf(output_file, " '\\\\%c", s[2]);
  1025.             s += 2;
  1026.             while (*++s != '\'')
  1027.             putc(*s, output_file);
  1028.             putc('\'', output_file);
  1029.         }
  1030.         else
  1031.             fprintf(output_file, " '%c'", s[1]);
  1032.         }
  1033.         else
  1034.         fprintf(output_file, " %s", s);
  1035.     }
  1036.     if (!rflag) ++outline;
  1037.     fprintf(output_file, "\",\n");
  1038.     }
  1039.  
  1040.     if (!rflag) outline += 2;
  1041.     fprintf(output_file, "};\n#endif\n");
  1042. }
  1043.  
  1044.  
  1045. output_stype()
  1046. {
  1047.     if (!unionized && ntags == 0)
  1048.     {
  1049.     outline += 3;
  1050.     fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
  1051.     }
  1052. }
  1053.  
  1054.  
  1055. output_trailing_text()
  1056. {
  1057.     register int c, last;
  1058.     register FILE *in, *out;
  1059.  
  1060.     if (line == 0)
  1061.     return;
  1062.  
  1063.     in = input_file;
  1064.     out = code_file;
  1065.     c = *cptr;
  1066.     if (c == '\n')
  1067.     {
  1068.     ++lineno;
  1069.     if ((c = getc(in)) == EOF)
  1070.         return;
  1071.     if (!lflag)
  1072.     {
  1073.         ++outline;
  1074.         fprintf(out, line_format, lineno, input_file_name);
  1075.     }
  1076.     if (c == '\n')
  1077.         ++outline;
  1078.     putc(c, out);
  1079.     last = c;
  1080.     }
  1081.     else
  1082.     {
  1083.     if (!lflag)
  1084.     {
  1085.         ++outline;
  1086.         fprintf(out, line_format, lineno, input_file_name);
  1087.     }
  1088.     do { putc(c, out); } while ((c = *++cptr) != '\n');
  1089.     ++outline;
  1090.     putc('\n', out);
  1091.     last = '\n';
  1092.     }
  1093.  
  1094.     while ((c = getc(in)) != EOF)
  1095.     {
  1096.     if (c == '\n')
  1097.         ++outline;
  1098.     putc(c, out);
  1099.     last = c;
  1100.     }
  1101.  
  1102.     if (last != '\n')
  1103.     {
  1104.     ++outline;
  1105.     putc('\n', out);
  1106.     }
  1107.     if (!lflag)
  1108.     fprintf(out, line_format, ++outline + 1, code_file_name);
  1109. }
  1110.  
  1111.  
  1112. output_semantic_actions()
  1113. {
  1114.     register int c, last;
  1115.     register FILE *out;
  1116.  
  1117.     fclose(action_file);
  1118.     action_file = fopen(action_file_name, "r");
  1119.     if (action_file == NULL)
  1120.     open_error(action_file_name);
  1121.  
  1122.     if ((c = getc(action_file)) == EOF)
  1123.     return;
  1124.  
  1125.     out = code_file;
  1126.     last = c;
  1127.     if (c == '\n')
  1128.     ++outline;
  1129.     putc(c, out);
  1130.     while ((c = getc(action_file)) != EOF)
  1131.     {
  1132.     if (c == '\n')
  1133.         ++outline;
  1134.     putc(c, out);
  1135.     last = c;
  1136.     }
  1137.  
  1138.     if (last != '\n')
  1139.     {
  1140.     ++outline;
  1141.     putc('\n', out);
  1142.     }
  1143.  
  1144.     if (!lflag)
  1145.     fprintf(out, line_format, ++outline + 1, code_file_name);
  1146. }
  1147.  
  1148.  
  1149. free_itemsets()
  1150. {
  1151.     register core *cp, *next;
  1152.  
  1153.     FREE(state_table);
  1154.     for (cp = first_state; cp; cp = next)
  1155.     {
  1156.     next = cp->next;
  1157.     FREE(cp);
  1158.     }
  1159. }
  1160.  
  1161.  
  1162. free_shifts()
  1163. {
  1164.     register shifts *sp, *next;
  1165.  
  1166.     FREE(shift_table);
  1167.     for (sp = first_shift; sp; sp = next)
  1168.     {
  1169.     next = sp->next;
  1170.     FREE(sp);
  1171.     }
  1172. }
  1173.  
  1174.  
  1175.  
  1176. free_reductions()
  1177. {
  1178.     register reductions *rp, *next;
  1179.  
  1180.     FREE(reduction_table);
  1181.     for (rp = first_reduction; rp; rp = next)
  1182.     {
  1183.     next = rp->next;
  1184.     FREE(rp);
  1185.     }
  1186. }
  1187.